package org.ssm.footstep.plugin.device.android;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;

import org.ssm.footstep.plugin.device.IDevice;
import org.ssm.footstep.util.Utility;

import com.android.ddmlib.MultiLineReceiver;
import com.android.ddmlib.RawImage;

public class AndroidDevice extends IDevice {
	public class LogCatOuputReceiver extends MultiLineReceiver {

	    public boolean isCancelled = false;

	    public LogCatOuputReceiver() {
	        super();

	        setTrimLine(false);
	    }

	    @Override
	    public void processNewLines(String[] lines) {
	        if (isCancelled == false) {
	        	for(String line : lines) {
	        		if(line.trim().length() != 0) {
	        			notifyDeviceLog(line);
	        		}
	        	}
	        }
	    }

	    public boolean isCancelled() {
	        return isCancelled;
	    }
	}
	
	private com.android.ddmlib.IDevice mDevice = null;
	
	private Thread mLogCatThread = null;
	private Thread mDeviceScreenShotThread = null;
	
	public AndroidDevice(com.android.ddmlib.IDevice device) {
		mDevice = device;
	}
	
	@Override
	public void start() {
		mLogCatThread = new Thread("LogCat") {
			@Override
			public void run() {
				try {
					mDevice.executeShellCommand("logcat -c", new LogCatOuputReceiver());
					mDevice.executeShellCommand("logcat -v time", new LogCatOuputReceiver());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		};
			
		mDeviceScreenShotThread = new Thread("DeviceScreenShot") {
			@Override
			public void run() {
				do {
					Image image = getDeviceScreenShot();
					if(image == null) {
						
					} else {
						notifyDeviceScreenShot(image);
					}
					
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} while(true);
			}
		};
		
		mDeviceScreenShotThread.start();
		mLogCatThread.start();
	}

	@Override
	public void stop() {
		mDeviceScreenShotThread.stop();
		mLogCatThread.stop();
	}

	@Override
	public DEVICE_STATE getDeviceState() {
		return mDevice.isOnline() ? DEVICE_STATE.ONLINE : DEVICE_STATE.OFFLINE;
	}

	@Override
	public Map<String, String> getProperties() {
		return mDevice.getProperties();
	}

	@Override
	public String getProperty(String key, String defValue) {
		String value = mDevice.getProperty(key);
		if(Utility.isEmpty(value)) {
			return defValue;
		} else {
			return value;
		}
	}

	@Override
	public Image getDeviceScreenShot() {
		Image image = null;
		
		try {
			RawImage rawImage = mDevice.getScreenshot();
			image = convertRawImageToImage(rawImage);
			Utility.Log("AndroidDevice getDeviceScreenShot" + image);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return image;
	}

	private Image convertRawImageToImage(RawImage rawImage) {
		if(rawImage == null) {
			return null;
		}
		
		int width2 = rawImage.width;
		int height2 = rawImage.height;
		BufferedImage image = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_RGB);

		int index = 0;
		int indexInc = rawImage.bpp >> 3;
		for (int y = 0; y < rawImage.height; y++) {
			for (int x = 0; x < rawImage.width; x++, index += indexInc) {
				int value = rawImage.getARGB(index);
				image.setRGB(x, y, value);
			}
		}
		
		return image;
	}

	@Override
	public String getDeviceName() {
		// TODO Auto-generated method stub
		return mDevice.getSerialNumber();
	}
}
